package com.example.springbootnettydemo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;  
import io.netty.channel.nio.NioEventLoopGroup;  
import io.netty.channel.socket.SocketChannel;  
import io.netty.channel.socket.nio.NioServerSocketChannel;  
import io.netty.handler.codec.string.StringDecoder;  
import io.netty.handler.codec.string.StringEncoder;  
  
public class NettyServer {  
  
    private final int port;  
  
    public NettyServer(int port) {  
        this.port = port;  
    }  
  
    public void start() throws Exception {  
        EventLoopGroup bossGroup = new NioEventLoopGroup(); // 用于接收进来的连接  
        EventLoopGroup workerGroup = new NioEventLoopGroup(); // 用于处理已经被接收的连接  
        try {  
            ServerBootstrap b = new ServerBootstrap();  
            b.group(bossGroup, workerGroup)  
                .channel(NioServerSocketChannel.class) // 使用Nio通道类型  
                .childHandler(new ChannelInitializer<SocketChannel>() { // 添加一个处理器来处理业务  
                    @Override  
                    protected void initChannel(SocketChannel ch) throws Exception {  
                        ChannelPipeline p = ch.pipeline();  
                        p.addLast(new StringDecoder()); // 解码器，将接收到的字节解码成字符串  
                        p.addLast(new StringEncoder()); // 编码器，将发送的字符串编码成字节  
                        p.addLast(new SimpleChannelInboundHandler<String>() { // 自定义处理器  
                            @Override  
                            protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {  
                                System.out.println("服务器收到消息: " + msg);  
                                // 收到什么则返回什么  
                                ctx.writeAndFlush(msg);  
                            }  
  
                            @Override  
                            public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
                                cause.printStackTrace();  
                                ctx.close();  
                            }  
                        });  
                    }  
                })  
                .option(ChannelOption.SO_BACKLOG, 128)  
                .childOption(ChannelOption.SO_KEEPALIVE, true);  
  
            // 绑定端口并开始接收进来的连接  
            ChannelFuture f = b.bind(port).sync();  
  
            // 等待服务器socket关闭  
            f.channel().closeFuture().sync();  
        } finally {  
            // 优雅地关闭所有线程组  
            bossGroup.shutdownGracefully();  
            workerGroup.shutdownGracefully();  
        }  
    }  
  
    public static void main(String[] args) throws Exception {  
        int port = 8080; // 可以从配置文件中读取  
        new NettyServer(port).start();  
    }  
}